#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>

// wc [filename]：依次输出行数/字数/字节数

int lineSum = 0;
int wordSum = 0;
int byteSum = 0;

int calcLines(char *filepath);
int calcWords(char *filepath);
void wc(char *arg);


int main(int argc, char *argv[]) {
    for (int i = 1; i < argc; ++i) {
        wc(argv[i]);
    }
    if (argc > 2) {
        // 如果文件参数路径大于2，打印总用量
        // 输出顺序：行数、字数、字节数
        printf("  %d\t%d\t%d\t总用量\t\n", lineSum, wordSum, byteSum);
    }
}

int calcLines(char *filepath) {
    FILE *fp;
    char chr;
    int lines = 0;

    if ((fp = fopen(filepath, "r")) == NULL) {
        // 文件不存在
        printf("wc: %s: 文件读取失败", filepath);
        exit(1);
    }

    // getc 返回值为 int，需要转换
    chr = (char) getc(fp);
    while (chr != EOF) {
        if (chr == '\n') {
            ++lines;
        }
        chr = (char) getc(fp);
    }
    // 算上最后一行
    ++lines;

    fclose(fp);
    
    return lines;
}

int calcWords(char *filepath) {
    FILE *fp;
    int words = 0;

    if ((fp = fopen(filepath, "r")) == NULL) {
        // 文件不存在
        printf("wc: %s: 文件读取失败", filepath);
        exit(1);
    }

    /** 空格
     * 回车符(\r)
     * 换行符(\n)
     * 水平制表符(\t)
     * 垂直制表符(\v)
     * 换页符(\f)
     */

    char former, latter;
    former = (char) getc(fp);
    while (former != EOF) {
        latter = (char) getc(fp);

        // 统计字数的条件：前一个字符不为空格/换行符/制表符
        // 后一个字符为空格/换行符/制表符/EOF中的一个
        if
        ((former != ' ' && former != '\r' && former != '\n' && former != '\t' && former != '\v' && former != '\f')
        &&
        (latter == ' ' || latter == '\r' || latter == '\n' && latter == '\t' && latter == '\v' || latter == '\f' || latter == EOF)) {
            words++;
        }
        former = latter;
    }
  
    fclose(fp);
    
    return words;
}

void wc(char *arg) {
    // 输出顺序：行数、字数、字节数
    struct stat st;
    if (stat(arg, &st) < 0) {
        // 未找到
        printf("wc: %s: 没有那个文件或目录\n", arg);
        exit(1);
    }
    if (st.st_mode & S_IFMT == S_IFDIR) {
        // 目录文件
        printf("wc: %s: 是一个目录\n", arg);
        printf("  0\t0\t%d\t%s\t\n", (int) st.st_size, arg);
    } else {
        int lineCnt = calcLines(arg);
        int wordCnt = calcWords(arg);
        int byteCnt = (int) st.st_size;
        printf("  %d\t%d\t%d\t%s\t\n", lineCnt, wordCnt, byteCnt, arg);

        lineSum += lineCnt;
        wordSum += wordCnt;
        byteSum += byteCnt;
    }
}